package com.csun.cmny.provider.device.card.entity;

import com.csun.cmny.provider.device.card.CardMessageEncoder;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;
import org.apache.commons.codec.binary.Hex;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Random;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-12-04 09:46
 * @Description:
 */
@Data
public class CardCmdEntity {

    /**
     * 标志码
     */
    public byte start = 0x7e;

    /**
     * 设备SN
     */
    public byte[] sn = new byte[16];

    /**
     * 密码
     */
    public byte[] password = new byte[4];

    /**
     * 信息代码
     */
    public byte[] code = new byte[4];

    /**
     * 分类
     */
    public byte type;

    /**
     * 命令
     */
    public byte cmd;

    /**
     * 参数
     */
    public byte param;

    /**
     * 数据长度
     */
    public byte[] length = new byte[4];

    /**
     * 数据
     */
    public byte[] data;

    /**
     * 检验值 -- 命令中所有字节都想加然后取尾子节
     */
    public byte check = 0x00;

    /**
     * 标志码
     */
    public byte end = 0x7e;

    public byte[] getBytes() {

        ByteBuf buf = Unpooled.buffer(34 + this.data.length);
        buf.writeByte(this.start);
        buf.writeBytes(this.sn);
        buf.writeBytes(this.password);
        buf.writeBytes(this.code);
        buf.writeByte(this.type);
        buf.writeByte(this.cmd);
        buf.writeByte(this.param);
        buf.writeBytes(this.length);
        buf.writeBytes(this.data);
        buf.writeByte(this.check);
        buf.writeByte(this.end);

        byte[] array = buf.array();
        this.check = getCheckSum(array, array.length);

        array[array.length - 2] = this.check;

        return array;
    }

    public void build(String deviceNo, byte[] password, byte[] code, byte[] data) {

        // 设备sn码 -- 长度16位
        this.setSn(deviceNo.getBytes());

        // 设备密码通信密码
        this.setPassword(password);

        // 信息代码
        /**
         * @author  chisj
         * @data    2020-12-03
         * @desc    随机数字
         */
        StringBuffer result = new StringBuffer();
        for(int i = 0; i < 4; i++) {
            result.append(Integer.toHexString(new Random().nextInt(16)));
        }

//        byte[] cmd = result.toString().getBytes();
//        this.setCode(code);
        this.setCode(result.toString().getBytes());

        // 数据
        this.setData(data);
    }

    /**
     * 除标志码和检验码，命令中所有字节都想加然后取尾子节
     *
     * @param buf
     * @param len
     *
     * @return
     */
    public static byte getCheckSum(byte[] buf, int len) {

        int checkSum = 0 & 0xff;

        if (buf == null) {
            return 0 & 0xff;
        }

        for (int i = 0; i < len - 2; i++) {
            checkSum += buf[i] & 0xff; // 转无符号
        }

        // 去掉包头包尾
        checkSum = checkSum - 126;

        byte[] b = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(checkSum).array();

        // 命令中所有字节都想加然后取尾子节
        return b[b.length - 1];
    }

    public static void main(String[] args) {

        StringBuffer result = new StringBuffer();
        for(int i = 0; i < 4; i++) {
            result.append(Integer.toHexString(new Random().nextInt(16)));
        }

        byte[] cmd = result.toString().getBytes();

        System.out.println("result = " + result.toString());

        System.out.println("result hex = " + CardMessageEncoder.format(Hex.encodeHexString(cmd)));
    }
}


